﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BIZModel;

namespace BIZMA.BL.Security
{
    public class SecurityBL : BaseBL
    {

        #region system
        /// <summary>
        /// Objekttypen för systemfunktioner om de hämtas på samma sätt som systemobjetfunctions. Det finns ingen typeof(xxx) som matchar detta.
        /// <remarks>Kolla i HasSysFunction(Guid userId, string functionType, bool checkSA) hur det används</remarks>
        /// <seealso cref="HasSysFunction"/>
        /// </summary>
        public const string OBJECTTYPE_SYSTEM = "#System";
        /// <summary>
        /// Kan skapa systemgrupper och hantera rättigheter
        /// </summary>
        public const string SYSFUNCTION_SYSTEM_SYSTEMGROUPS = "SYS_SYSTEMGROUPS";
        /// <summary>
        /// Kan skapa, ändra, radera grupper i systemet. Gäller ej systemgrupper!
        /// </summary>
        public const string SYSFUNCTION_SYSTEM_USERGROUPS = "SYS_USERGROUPS";
        /// <summary>
        /// Kan skapa, ändra, radera användare i systemet
        /// </summary>
        public const string SYSFUNCTION_SYSTEM_USERADMIN = "SYS_USERADMIN";
        /// <summary>
        /// Kan skapa roller och hantera rättigheter
        /// </summary>
        public const string SYSFUNCTION_SYSTEM_ROLES = "SYS_ROLES";
        /// <summary>
        /// Kan skapa roller och hantera rättigheter
        /// </summary>
        public const string SYSFUNCTION_SYSTEM_FILEARCHIVE = "SYS_FILEARCHIVE";
        /// <summary>
        /// Användargruppen som är SA
        /// </summary>
        public static Guid USERGROUP_SA = Guid.Parse("00000000-0000-0000-0000-000000000001");
        #endregion


        #region FileArchive
        /// <summary>
        /// Objekttypen för företag dvs samma som typeof(Folder).FullName
        /// </summary>
        public const string OBJECTTYPE_FOLDER = "BIZModel.Folder";
        /// <summary>
        /// Kan se mappen och filerna i mappen
        /// </summary>
        public const string OBJFUNCTION_FOLDER_READ = "FOLDER_READ";
        /// <summary>
        /// Kan skapa/ändra/radera mapp
        /// </summary>
        public const string OBJFUNCTION_FOLDER_EDIT = "FOLDER_EDIT";
        /// <summary>
        /// Kan skapa/ändra/radera filerna i mappen
        /// </summary>
        public const string OBJFUNCTION_FOLDER_EDITFILES = "FILES_EDIT";
        /// <summary>
        /// Kan ladda upp filer i mappen och redigera egna filer i mappen
        /// </summary>
        public const string OBJFUNCTION_FOLDER_UPLOAD = "FOLDER_UPLOAD";

        #endregion

        #region democompany
        /// <summary>
        /// Objekttypen för företag dvs samma som typeof(DemoCompany).FullName
        /// </summary>
        public const string OBJECTTYPE_COMPANY = "BIZModel.DemoCompany";
        /// <summary>
        /// Koppla och editera anställda till ett företag
        /// </summary>
        public const string OBJFUNCTION_COMPANY_EDITEMPLOYEES = "COMPANY_EDIT_EMPLOYEES";
        /// <summary>
        /// Editera ett befintligt företag och hantera rättigheter
        /// </summary>
        public const string OBJFUNCTION_COMPANY_EDIT = "COMPANY_EDIT";
        /// <summary>
        /// Se information om ett företag och dess anställda
        /// </summary>
        public const string OBJFUNCTION_COMPANY_READ = "COMPANY_READ";

        public const string SYSFUNCTION_COMPANY_ADMIN = "SYS_COMPANY_ADMIN";
        #endregion

        /// <summary>
        /// Kollar om inloggad användaren har efterfrågad funktionsstyp kopplad till de systemgrupper som man ingår i. Kollar även om användaren är SA
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="functionType"></param>
        /// <returns></returns>
        public static bool HasSysFunction(string functionType)
        {
            return HasSysFunction(BaseBL.UserId,functionType);
        }
        /// <summary>
        /// Kollar om användaren har efterfrågad funktionsstyp kopplad till de systemgrupper som man ingår i. Kollar även om användaren är SA
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="functionType"></param>
        /// <returns></returns>
        public static bool HasSysFunction(Guid userId, string functionType)
        {
            return HasSysFunction(userId, functionType, true);

           
        }

        /// <summary>
        /// Kollar om användaren har efterfrågad funktionsstyp kopplad till de systemgrupper som man ingår i. 
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="functionType"></param>
        /// <param name="checkSA">Kolla om användaren är SA. Detta görs redan i HasSysObjectFunction och om den funktionen körts innan så är detta onödigt</param>
        /// <returns></returns>
        public static bool HasSysFunction(Guid userId, string functionType, bool checkSA)
        {
            if (userId == BaseBL.UserId)
            {
                if (checkSA && CurrentUserProfile.isSA)
                {
                    return true;
                }

                if (CurrentUserProfile.SystemFunctions.Exists(q => q.FunctionKey == functionType && q.ObjectType == OBJECTTYPE_SYSTEM))
                {
                    return true;
                }
            }
            else
            {
                if (checkSA && GetEnt().Security_UserIsSA(userId).First().Value)
                {
                    return true;
                }


                if (GetEnt().Security_HasSystemFunction(userId, functionType).First().Value)
                {
                    return true;
                }
            }
            

            return false;
        }

        /// <summary>
        /// Kollar om användaren har efterfrågad objektfunktion kopplad som (global) systemobjektfunktion till de systemgrupper som användaren ingår i. 
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="functionType"></param>
        /// <param name="objectType"></param>
        /// <returns></returns>
        public static bool HasSysObjectFunction(Guid userId, string functionType, string objectType)
        {

            if (userId == BaseBL.UserId)
            {
                if (CurrentUserProfile.isSA)
                {
                    return true;
                }
                if (CurrentUserProfile.SystemFunctions.Exists(q => q.FunctionKey == functionType && q.ObjectType == objectType))
                {
                    return true;
                }             
            }
            else
            {
                if (BaseBL.GetEnt().Security_UserIsSA(userId).First().Value)
                {
                    return true;
                }

                Security_UserSystemFunction Sfs = BaseBL.GetEnt().Security_GetUserSystemFunctions(userId).FirstOrDefault(q => q.FunctionKey == functionType && q.ObjectType == objectType);

                if (Sfs != null)
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Kollar om inloggad användare har rättigheter till efterfrågad funktion på ett objekt.
        /// </summary>
        /// <param name="objectId"></param>
        /// <param name="objectType"></param>
        /// <param name="functionType"></param>
        /// <returns></returns>
        public static bool HasObjectFunction(Guid objectId, string objectType, string functionType)
        {
            return HasObjectFunction(BaseBL.UserId, objectId, objectType, functionType);
        }

        /// <summary>
        /// Kollar om inloggad användare har rättigheter till efterfrågad funktion på ett objekt. Kollar samtidigit som användaren har systemglobala rättigheter dvs (HasSysFunction)
        /// </summary>
        /// <param name="objectId"></param>
        /// <param name="objectType"></param>
        /// <param name="functionType"></param>
        /// <returns></returns>
        public static bool HasObjectFunction(Guid objectId, string objectType, string functionType, string sysFunctionType)
        {
            if(HasSysFunction(sysFunctionType))
                return true;
            else           
                return HasObjectFunction(BaseBL.UserId, objectId, objectType, functionType);
        }

        /// <summary>
        /// Kollar om användaren har rättigheter till efterfrågad funktion på ett objekt.
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="objectId"></param>
        /// <param name="objectType"></param>
        /// <param name="functionType"></param>
        /// <returns></returns>
        public static bool HasObjectFunction(Guid userId, Guid objectId, string objectType, string functionType)
        {
            //Kolla om användaren har objektfunktionen som en systemfunktion (dvs att den gäller för alla objekten av denna typ)
            if (HasSysObjectFunction(userId, functionType, objectType))
            {
                return true;
            }

            //Här kan man lägga in default regler för rättigheter tex om en funktion (ex admin) gäller före andra funktioner för objekttypen
            
            if (objectType == OBJECTTYPE_COMPANY && HasSysFunction(userId, SYSFUNCTION_COMPANY_ADMIN))
            {
                return true;
            }
                        
            //Om inget annat har hittats kolla om användaren har efterfrågad funktionsrättighet på specifikt objekt
            return BaseBL.GetEnt().Security_HasFunction(userId, objectId, objectType, functionType).First().Value;
            
        }
    }
}